package tps12.axwax.client.models;

import java.util.Collection;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;

import tps12.axwax.client.PuzzleClient.PuzzleDescription;
import tps12.axwax.client.PuzzleClientImpl;


/**
 * The presentation model for selecting from a list of puzzles.
 * 
 * @author Travis
 *
 */
public class SelectPuzzleModel {
	
	/**
	 * Constructs a select puzzle presentation model object with the given event
	 * handlers.
	 * 
	 * @param listChanged the handler for list change events
	 */
	public SelectPuzzleModel(PuzzleListChangedHandler listChanged) {
		handlers = new HandlerManager(this);
		
		handlers.addHandler(LIST_CHANGED_TYPE, listChanged);
		
		puzzles.getPuzzleList(new AsyncCallback<Collection<PuzzleDescription>>() {
			@Override public void onFailure(Throwable caught) {
				GWT.log("Get puzzle list failed", caught);
			}

			@Override public void onSuccess(Collection<PuzzleDescription> result) {
				handlers.fireEvent(new PuzzleListChangedEvent(result));
			}
		});
	}

	public String baseUrl() { return puzzles.baseUrl; }
	
	private final PuzzleClientImpl puzzles =
		new PuzzleClientImpl(new PuzzleClientImpl.GwtRequestBuilderFactory());
	
	private final HandlerManager handlers;
	
	private static final GwtEvent.Type<PuzzleListChangedHandler> LIST_CHANGED_TYPE =
		new GwtEvent.Type<PuzzleListChangedHandler>();
	
	/**
	 * Handles puzzle list change events.
	 */
	public interface PuzzleListChangedHandler extends EventHandler {
		/**
		 * Called when the puzzle list changes.
		 * @param list the list of puzzles
		 */
		public void onChanged(Collection<PuzzleDescription> list);
	}
	
	/**
	 * Puzzle list changed event object.
	 */
	public class PuzzleListChangedEvent extends GwtEvent<PuzzleListChangedHandler> {
		/**
		 * Constructs a puzzle list changed event with the given new list value. 
		 * @param value the new list of puzzles
		 */
		public PuzzleListChangedEvent(Collection<PuzzleDescription> value) {
			list = value;
		}
		
		private final Collection<PuzzleDescription> list;
		
		@Override protected void dispatch(PuzzleListChangedHandler handler) {
			handler.onChanged(list);
		}

		@Override public GwtEvent.Type<PuzzleListChangedHandler> getAssociatedType() {
			return LIST_CHANGED_TYPE;
		}
	}
}
